package com.googlecode.vmock;

/**
 * Interface representing an expected result of a mocked call. The result is
 * chosen by the end user through the {@link MockBuilder} API.
 * 
 * @author marcin.jagus
 */
interface ExpectedCallResult extends Comparable<ExpectedCallResult> {

    /**
     * Returns the result of a mocked call. Returned result can be dependant
     * on the given parameters of a mocked call.<br/>
     * Calls to this method increment <code>timesCalled</code< property by 1.
     * 
     * @param params Given parameters of a mocked call
     * @return Expected result
     * @throws Throwable if expect result is a throwable or if the internal
     * logic of the implementor has failed with an exception
     */
    Object getResult(Object[] params) throws Throwable;
    
    /**
     * Returns the number of times the expected result should be returned.
     * 
     * @return Number of times the expected result should be returned or {@link MockBuilder#ANY_TIMES}
     * if it should be returned any times.
     */
    int getTimesExpected();
    
    /**
     * Sets the numer of times the expected result should be returned.
     * 
     * @param count Number of times the expected result should be returned. Can
     * be {@link MockBuilder#ANY_TIMES}.
     */
    void setTimesExpected(int count);
    
    /**
     * Returns the number of times this object was asked for a result.
     * 
     * @return Number of times this object was asked for a result
     */
    int getTimesInvoked();
    
    /**
     * A recorded call for which this expected result was created.
     * 
     * @return A recorded call. Can never be <code>null</code>.
     */
    RecordedCall getRecordedCall();
    
    /**
     * Checks if a given array of objects is matched by all the matchers defined
     * in recorded call returned by {@link ExpectedCallResult#getRecordedCall()}
     * method.
     * 
     * @param params Given array of objects. Cannot be null.
     * @return <code>true</code> if all the objects in a given array are matched
     * by adequate matchers
     */
    boolean matches(Object[] params);
}
